import { computed, onMounted, ref } from "vue";
import { ElMessageBox } from "element-plus";
import { useListPage } from "@/composables/useListPage";
import { message } from "@/utils/message";
import { useDialog } from "@/composables/useDialog";
import recordApi, {
  type NotifyRecordItem,
  type NotifyRecipientItem,
  type NotifyRecordListResult,
  type NotifyRecordListParams,
  type CreateRecordPayload
} from "@/api/system/notify/record";
import templateApi from "@/api/system/notify/template";

interface RecordFilterForm {
  keyword: string;
  status: string | number;
  channel: string;
  template_id: string | number;
  template_type: string;
  dateRange: [string, string] | [];
}

type RecordFilterParams = RecordFilterForm & {
  page: number;
  page_size: number;
};

interface TemplateOption {
  id: number;
  name: string;
  type: string;
}

const DEFAULT_FILTER: RecordFilterForm = {
  keyword: "",
  status: "",
  channel: "",
  template_id: "",
  template_type: "",
  dateRange: []
};

const DEFAULT_CHANNEL_OPTIONS = ["websocket", "wechat", "sms", "email"];

const DEFAULT_STATUS_OPTIONS = [
  { label: "全部状态", value: "" },
  { label: "待发送", value: 0 },
  { label: "已发送", value: 1 },
  { label: "发送失败", value: 2 },
  { label: "已读", value: 3 },
  { label: "已取消", value: 4 }
];

const STATUS_META: Record<
  number,
  {
    label: string;
    tag: "primary" | "success" | "warning" | "danger" | "info";
  }
> = {
  0: { label: "待发送", tag: "warning" },
  1: { label: "已发送", tag: "success" },
  2: { label: "发送失败", tag: "danger" },
  3: { label: "已读", tag: "success" },
  4: { label: "已取消", tag: "info" }
};

const CHANNEL_LABELS: Record<string, string> = {
  websocket: "WebSocket",
  wechat: "微信",
  sms: "短信",
  email: "邮箱",
  dingTalk: "钉钉",
  dingtalk: "钉钉",
  lark: "飞书",
  feishu: "飞书",
  app: "App",
  push: "推送",
  system: "系统"
};

const toDateParams = (range: RecordFilterForm["dateRange"]) => {
  if (!Array.isArray(range) || range.length !== 2) {
    return { date_start: undefined, date_end: undefined };
  }
  return {
    date_start: range[0] ?? undefined,
    date_end: range[1] ?? undefined
  };
};

const uniqueChannels = (recipients: NotifyRecipientItem[]) => {
  const set = new Set<string>();
  recipients.forEach(recipient => {
    if (recipient?.channel) {
      set.add(String(recipient.channel));
    }
  });
  return Array.from(set);
};

export function useNotifyRecord() {
  const { openDialog } = useDialog();
  const templates = ref<Array<TemplateOption>>([]);
  const channelOptions = ref<Array<string>>([...DEFAULT_CHANNEL_OPTIONS]);
  const statusOptions = ref<Array<{ label: string; value: string | number }>>([
    ...DEFAULT_STATUS_OPTIONS
  ]);

  const detailVisible = ref(false);
  const detailLoading = ref(false);
  const detailRecord = ref<NotifyRecordItem | null>(null);
  const detailSelection = ref<Array<NotifyRecipientItem>>([]);

  const {
    formState: filterForm,
    pagination,
    dataList,
    loading,
    onSearch,
    resetForm,
    handlePageChange,
    handleSizeChange
  } = useListPage<RecordFilterForm, NotifyRecordItem, NotifyRecordListResult>(
    {
      fetch: (params: RecordFilterParams) =>
        recordApi.fetchList({
          ...params,
          template_id:
            params.template_id === "" ? undefined : params.template_id
        } as NotifyRecordListParams)
    },
    DEFAULT_FILTER,
    {},
    {
      paramsAdapter: params => {
        const { dateRange, ...rest } = params;
        const { date_start, date_end } = toDateParams(dateRange);
        return {
          ...rest,
          template_id:
            rest.template_id === "" ? undefined : Number(rest.template_id),
          date_start,
          date_end
        };
      },
      responseAdapter: response => {
        templates.value = response.templates ?? [];
        const remoteChannels =
          response.channels && response.channels.length > 0
            ? response.channels
            : DEFAULT_CHANNEL_OPTIONS;
        channelOptions.value = Array.from(new Set(remoteChannels));

        const remoteStatuses = response.statuses ?? [];
        if (remoteStatuses.length > 0) {
          statusOptions.value = [
            { label: "全部状态", value: "" },
            ...remoteStatuses
          ];
        } else {
          statusOptions.value = [...DEFAULT_STATUS_OPTIONS];
        }

        return {
          list: response.list ?? [],
          total: response.total ?? 0,
          pageSize: response.pageSize ?? 10,
          currentPage: response.currentPage ?? 1
        };
      }
    }
  );

  const columns: TableColumnList = [
    { label: "消息ID", prop: "id", width: 100 },
    { label: "模板", prop: "template", minWidth: 220, slot: "template" },
    { label: "标题", prop: "title", minWidth: 220, align: "left" },
    { label: "渠道", prop: "channels", minWidth: 160, slot: "channels" },
    { label: "状态", prop: "status", width: 120, slot: "status" },
    { label: "发送时间", prop: "sent_at", width: 180 },
    { label: "创建时间", prop: "create_time", width: 180 },
    {
      label: "操作",
      prop: "operation",
      width: 220,
      fixed: "right",
      slot: "operation"
    }
  ];

  const tableData = computed(() => dataList.value ?? []);

  const statusTagType = (status: number) => {
    return STATUS_META[status]?.tag ?? "info";
  };

  const statusLabel = (status: number, fallback?: string) => {
    if (fallback) return fallback;
    return STATUS_META[status]?.label ?? `状态 ${status}`;
  };

  const channelLabel = (channel: string) => {
    const key = channel?.toString?.() ?? "";
    const lower = key.toLowerCase();
    return CHANNEL_LABELS[lower] ?? CHANNEL_LABELS[key] ?? key ?? "-";
  };

  const fetchRecords = async () => {
    await onSearch();
  };

  const handleSearch = async () => {
    filterForm.page = 1;
    await onSearch();
  };

  const handleResetFilters = async () => {
    await resetForm();
  };

  const closeDetail = () => {
    detailVisible.value = false;
    detailRecord.value = null;
    detailSelection.value = [];
  };

  const loadDetail = async (id: number) => {
    detailLoading.value = true;
    try {
      const record = await recordApi.fetchDetail(id);
      detailRecord.value = record;
      detailSelection.value = [];
    } catch (error: any) {
      message(error?.message ?? "加载通知详情失败", { type: "error" });
      closeDetail();
    } finally {
      detailLoading.value = false;
    }
  };

  const openDetail = async (row: NotifyRecordItem) => {
    detailVisible.value = true;
    await loadDetail(row.id);
  };

  const confirmResend = async (messageText: string) => {
    try {
      await ElMessageBox.confirm(messageText, "重新推送确认", {
        type: "warning",
        confirmButtonText: "确认",
        cancelButtonText: "取消"
      });
    } catch {
      return false;
    }
    return true;
  };

  const resend = async (id: number, recipientIds?: number[]) => {
    await recordApi.resend(id, {
      recipient_ids:
        recipientIds && recipientIds.length > 0 ? recipientIds : undefined
    });
    message("已提交重新推送任务", { type: "success" });
    await fetchRecords();
    if (detailVisible.value && detailRecord.value?.id === id) {
      await loadDetail(id);
    }
  };

  const handleResend = async (row: NotifyRecordItem) => {
    const confirmed = await confirmResend(
      `确认重新推送通知「${row.title}」吗？`
    );
    if (!confirmed) return;
    try {
      await resend(row.id);
    } catch (error: any) {
      message(error?.message ?? "重新推送失败", { type: "error" });
    }
  };

  const handleResendSingle = async (recipient: NotifyRecipientItem) => {
    if (!detailRecord.value) return;
    const confirmed = await confirmResend(
      `确认重新推送至「${channelLabel(recipient.channel)} - ${recipient.target_id}」吗？`
    );
    if (!confirmed) return;

    try {
      await resend(detailRecord.value.id, [recipient.id]);
    } catch (error: any) {
      message(error?.message ?? "重新推送失败", { type: "error" });
    }
  };

  const handleResendSelected = async () => {
    if (!detailRecord.value) return;
    const ids = detailSelection.value.map(item => item.id);
    if (ids.length === 0) {
      message("请选择需要重推的接收人", { type: "warning" });
      return;
    }
    const confirmed = await confirmResend(
      `确认重新推送选中的 ${ids.length} 个接收人吗？`
    );
    if (!confirmed) return;
    try {
      await resend(detailRecord.value.id, ids);
    } catch (error: any) {
      message(error?.message ?? "重新推送失败", { type: "error" });
    }
  };

  const handleDetailSelectionChange = (rows: NotifyRecipientItem[]) => {
    detailSelection.value = rows ?? [];
  };

  const submitCreate = async (payload: CreateRecordPayload) => {
    await recordApi.create(payload);
    message("通知已创建", { type: "success" });
    await fetchRecords();
  };

  const ensureTemplateOptions = async () => {
    if (templates.value.length > 0) return;
    try {
      const result = await templateApi.fetchList({ page: 1, page_size: 50 });
      templates.value = (result.list ?? []).map(item => ({
        id: item.id,
        name: item.name,
        type: item.type
      }));
      if (result.channels && result.channels.length > 0) {
        channelOptions.value = Array.from(new Set(result.channels));
      }
    } catch (error: any) {
      message(error?.message ?? "加载模板列表失败", { type: "error" });
    }
  };

  const openCreate = async () => {
    await ensureTemplateOptions();
    openDialog(() => import("../components/record-form.vue"), {
      title: "新增通知",
      width: "720px",
      props: {
        templates: templates.value.slice(),
        channelOptions: channelOptions.value.slice(),
        onSubmit: submitCreate,
        loadTemplate: templateApi.fetchDetail
      }
    });
  };

  onMounted(() => {
    fetchRecords();
  });

  return {
    filterForm,
    pagination,
    tableData,
    columns,
    loading,
    templates,
    channelOptions,
    statusOptions,
    detailVisible,
    detailLoading,
    detailRecord,
    detailSelection,
    handleSearch,
    handleResetFilters,
    handlePageChange,
    handleSizeChange,
    openDetail,
    closeDetail,
    handleResend,
    handleResendSelected,
    handleResendSingle,
    handleDetailSelectionChange,
    channelLabel,
    statusLabel,
    statusTagType,
    uniqueChannels,
    openCreate
  };
}
